# recommendation/models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models import JSONField
from problems.models import Problem
from users.models import UserProfile


class SolvedProblem(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='solved_problems')
    problem = models.ForeignKey(Problem, on_delete=models.CASCADE, related_name='solved_by_users')
    # related_name是反向关系访问

    class Meta:
        unique_together = ('user', 'problem')  # 每个用户的解决题目必须唯一

    def __str__(self):
        return f"{self.user.username} - {self.problem.problem_number}"

    def save_state(self):
        return {
            'problem_number': self.problem.problem_number,
        }

    @staticmethod
    def restore_state(user, state_data_list):
        # 首先，删除该用户的所有已解决问题记录
        user.solved_problems.all().delete()

        for state_data in state_data_list:
            problem = Problem.objects.get(problem_number=state_data['problem_number'])
            SolvedProblem.objects.get_or_create(
                user=user,
                problem=problem
            )

    @classmethod
    def fetch_and_store_user_problems_by_id(cls, user_id):
        """
        根据传入的用户ID爬取数据并将其存储到数据库中
        可用于数据初始化/更新
        """
        try:
            user = User.objects.get(id=user_id)

            uid = UserProfile.get_luogu_uid_by_user_id(user_id)

            # 调用爬取功能
            problem_numbers = get_user_problem_numbers_via_json(uid)
            new_problems = []  # 初始化一个列表来存储新增的Problem实例
            for number in problem_numbers:
                try:
                    problem_instance = Problem.objects.get(problem_number=number)
                    # 只有在 SolvedProblem 中尚不存在时，才创建新的记录
                    if not cls.objects.filter(user=user, problem=problem_instance).exists():
                        cls.objects.create(user=user, problem=problem_instance)
                        new_problems.append(problem_instance)  # 将新增的Problem实例添加到列表中
                except Problem.DoesNotExist:
                    # 如果指定的问题编号不存在，则可以在此处处理，例如记录日志或通知管理员
                    print(f"Problem with number {number} not found in the database.")
                except Exception as e:
                    print(f"An error occurred while adding problem: {e}")
            return new_problems  # 返回新增的Problem实例集合
        except User.DoesNotExist:
            print(f"No user found with user_id {user_id}")
            return []
        except Exception as e:
            print(f"An error occurred while initializing user problems for user_id={user_id}: {e}")

    @classmethod
    def add_solved_problem(cls, user_id, problem_number):
        """
        根据给定的用户 ID 和题目编号添加一个解决的题目记录。
        如果记录已存在，不会添加重复记录。
        :param user_id: 用户 ID
        :param problem_number: 题目编号
        :return: 返回创建的 SolvedProblem 实例或 None
        """
        try:
            user = User.objects.get(id=user_id)  # 获取用户实例
            problem = Problem.objects.get(problem_number=problem_number)  # 获取题目实例

            # 检查是否已存在该解决题目的记录
            if not cls.objects.filter(user=user, problem=problem).exists():
                solved_problem = cls.objects.create(user=user, problem=problem)
                return solved_problem
            else:
                print(f"Solved problem already exists for user {user.username} and problem {problem.problem_number}")
                return None

        except User.DoesNotExist:
            print(f"User with ID {user_id} does not exist.")
        except Problem.DoesNotExist:
            print(f"Problem with number {problem_number} does not exist.")
        except Exception as e:
            print(f"An error occurred while adding solved problem: {e}")
        return None

    @classmethod
    def delete_user_all_problems(cls, user_id):
        # 删除该用户的所有已解决问题记录

        try:
            user = User.objects.get(id=user_id)  # 获取用户实例
            deletion_count, _ = user.solved_problems.all().delete()
            return deletion_count

        except User.DoesNotExist:
            print(f"User with ID {user_id} does not exist.")
            return None

    @classmethod
    def remove_solved_problem(cls, user_id, problem_number):
        try:
            user = User.objects.get(id=user_id)
            problem = Problem.objects.get(problem_number=problem_number)
            solved_problem = cls.objects.get(user=user, problem=problem)
            solved_problem.delete()
            return True, "Solved problem record deleted successfully."
        except User.DoesNotExist:
            return False, "User not found."
        except Problem.DoesNotExist:
            return False, "Problem not found."
        except cls.DoesNotExist:
            return False, "Solved problem record does not exist."
        except Exception as e:
            return False, f"Error occurred: {str(e)}"


from django.db import models
from django.contrib.auth import get_user_model
from django.db.models import JSONField
from .services import select_random_problems, get_user_problem_numbers, get_user_problem_numbers_via_json


class RecommendationQueue(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='recommendation_queue')
    problem_numbers = JSONField(default=list)

    def __str__(self):
        return f"{self.user.username}'s recommendation queue"

    def enqueue(self, problem_number):
        if problem_number not in self.problem_numbers:
            if len(self.problem_numbers) >= 10:
                self.problem_numbers.pop(0)
            self.problem_numbers.append(problem_number)
            self.save()

    def dequeue(self):
        if self.problem_numbers:
            removed_problem = self.problem_numbers.pop(0)
            self.save()
            return removed_problem
        return None

    def reset_and_randomize_queue(self):
        """重置并随机填充推荐队列"""
        self.problem_numbers = select_random_problems(self.user, 10)
        self.save()